/** 
 * @file        delay.c
 * @brief       
 * @details     
 * @author   fulong
 * @date     Mar 28, 2014
 * @version  1.0
 * @par Copyright (c):
 *       GPLv2
 */

#include "delay.h"
#include "../dev/uart.h"

#define DELAY_MAX_NUM 16
typedef uint16 delay_typed;
extern uint32 time_1ms_tick;
typedef struct {
    delay_typed delay_time_used_flag;
    uint32 delay_time[DELAY_MAX_NUM];
    delay_typed delay_timeout;
}delay_time_mange_struct;
delay_time_mange_struct delay_time_manage;
#ifdef __R8C
void delay(uint16 us)
{
    while (us--)
    {
        /* 32 NOPs == 1 usecs */
        asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
        asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
        asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
        asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
        asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
        asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
        asm("nop"); asm("nop");
    }
}
#endif
#ifdef __STM32
//stm32 吞吐量1.25MIPS/Mhz
__asm  void delay(uint16 us)
{  
    lsl r0,r0,#3
lable
    subs r0,r0,#1
	cmp r0,#0
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    bne lable
    bx lr
}
#endif
void adjust_delay_timeout(void)
{
    uint8 count = 0;
    while (count < DELAY_MAX_NUM)
    {
        if ((delay_time_manage.delay_time_used_flag & (1 << count)) != 0)
        {
            if (delay_time_manage.delay_time[count] <= time_1ms_tick)
            {
                delay_time_manage.delay_timeout  |= (1 << count);
            }
        }
        count++;
    }
}
void delay_init(void)
{
    delay_time_manage.delay_time_used_flag = 0;
    delay_time_manage.delay_timeout = 0;
}
uint8 apply4delay(uint8 delay_id, uint16 delay_1ms)
{
    if (delay_id >= DELAY_MAX_NUM)
    {
        return (1);
    }
    if ((delay_time_manage.delay_time_used_flag & (1 << delay_id)) == 0)
    {
        delay_time_manage.delay_time[delay_id] = time_1ms_tick + delay_1ms;
        delay_time_manage.delay_time_used_flag |= (1 << delay_id);
        return (0);
    } else
    {
        return (2);
    }
}
uint32 get_time_counter(void)
{
    return (time_1ms_tick);
}
void clr_delay_flag(uint8 delay_id)
{
    delay_time_manage.delay_time_used_flag &= ~(1 << delay_id);
    delay_time_manage.delay_timeout &= ~(1 << delay_id);
}
uint8 get_delay_flag(uint8 delay_id)
{
    uint8 flagtmp = 0;
    if ((delay_time_manage.delay_timeout & (1 << delay_id)) != 0)
    {
        flagtmp = 1;
        clr_delay_flag(delay_id);
    }
    return (flagtmp);
}
uint8 no_clr_get_delay_flag(uint8 delay_id)
{
    return ((delay_time_manage.delay_timeout >> delay_id) & 0x1);
}
